package team02.server.bean;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;

import team02.client.core.test.Test;
import team02.client.core.test.question.Question;
import team02.client.core.test.question.QuestionAN;
import team02.client.core.test.question.QuestionS;
import team02.client.core.test.question.QuestionSC;
import team02.client.core.test.question.QuestionWR;
import team02.client.util.Pair;
import team02.server.model.MySQLModel;

public class QuestionBean extends MySQLModel {

	public static final String FIELD_NAME = "" + //
			" `id`," + // 1
			" `questionNo`," + // 2
			" `test_id`," + // 3
			" `type`," + // 4
			" `question_content`," + // 5
			" `selection_list`," + // 6
			" `write_list`," + // 7	
			" `answer_score_list`," + // 8
			" `anc_list`," + // 9
			" `ins_type`," + // 10
			" `timeout_style`," + // 11
			" `timeout_duration_1`," + // 12
			" `timeout_duration_2`"; // 13

	public static final String ANSWER_FIELD_NAME = "" + 
			"  `question_id`," + //1
			"  `examinee_id`," + //2
			"  `selections`," + //3
			"  `writes`," + //4
			"  `score`," +//5
			"  `ins_content`,"+//6
			"  `used_time`";//7

	private static final String AN_TYPE = "type";

	private static final String AN_SCORE = "score";

	private static final String AN_SELECT = "select";

	private static final String AN_WRITE = "write";

	private Question question;

	public QuestionBean(Connection connection) {
		super(connection);
		this.question = new Question();
	}

	public QuestionBean() {
		super(null);
		this.question = new Question();
	}

	@Override
	public int load() throws SQLException {
		String queryString = "SELECT " + FIELD_NAME + " FROM " + TABLE_QUESTION;
		if (question.getId() != 0) {
			queryString += " WHERE `id` = " + question.getId();
		} else return 1;

		try {
			initConnection();
			executeQuery(queryString);
			if (resultSet.next()) {
				loadQuestion(this.question, resultSet);
			}
			return 0;
		} finally {
			freeResources();
		}

	}

	public int loadAnswer(int examineeId) throws SQLException {
		//				"  `question_id`," + 
		//				"  `examinee_id`," + 
		//				"  `selections`," + 
		//				"  `writes`," + 
		//				"  `score`," + 
		//				"  `ins_content`";
		String queryString = "SELECT " + ANSWER_FIELD_NAME + " FROM " + TABLE_ANSWER + " WHERE `examinee_id` = "
				+ examineeId + " AND `question_id` = " + this.question.getId();
		try {
			initConnection();
			executeQuery(queryString);
			if (resultSet.next()) {
				JSONArray selections = new JSONArray(resultSet.getString(3));
				ArrayList<Integer> examineeSelection = new ArrayList<Integer>(selections.length());
				for (int i = 0; i < selections.length(); i++) {
					examineeSelection.add(selections.getInt(i));
				}
				this.question.setExamineeSelection(examineeSelection);

				JSONArray writes = new JSONArray(resultSet.getString(4));
				ArrayList<String> examineeWrite = new ArrayList<String>(writes.length());
				for (int i = 0; i < writes.length(); i++) {
					examineeWrite.add(writes.getString(i));
				}
				this.question.setExamineeWrite(examineeWrite);
				this.question.setScore(resultSet.getInt(5));
				this.question.setInsertContent(resultSet.getString(6));
				this.question.setUsedTime(resultSet.getLong("used_time"));
				return 0;
			}
			return 1;
		} finally {
			freeResources();
		}
	}

	private void loadQuestion(Question q, ResultSet resultSet) throws SQLException {
		//		" `id`," + // 1
		//		" `questionNo`," + // 2
		//		" `test_id`," + // 3
		//		" `type`," + // 4
		//		" `question_content`," + // 5
		//		" `selection_list`," + // 6
		//		" `write_list`," + // 7	
		//		" `answer_score_list`," + // 8
		//		" `anc_list`," + // 9
		//		" `ins_type`," + // 10
		//		" `timeout_style`," + // 11
		//		" `timeout_duration_1`," + // 12
		//		" `timeout_duration_2`"; // 13
		q.setId(resultSet.getInt(1));
		q.setQuestionNo(resultSet.getInt(2));
		q.setTestId(resultSet.getInt(3));
		q.setType(resultSet.getString(4));
		q.setContent(resultSet.getString(5));
		q.setExaminerInsertType(resultSet.getString(10));
		if (q.getType().equals(Question.TYPE_SELECTION)) {//SELECTION LIST
			JSONArray selectionListJSON = new JSONArray(resultSet.getString(6));
			int length = selectionListJSON.length();
			ArrayList<QuestionS> selectionList = new ArrayList<QuestionS>(length);
			for (int i = 0; i < length; i++) {
				QuestionS selection = new QuestionS(i + 1, selectionListJSON.getString(i), false);
				selectionList.add(selection);
			}
			q.setSelectionList(selectionList);
		} else {//WRITE LIST
			JSONArray writeListJSON = new JSONArray(resultSet.getString(7));
			int length = writeListJSON.length();
			ArrayList<QuestionWR> writeList = new ArrayList<QuestionWR>(length);
			for (int i = 0; i < length; i++) {
				QuestionWR write = new QuestionWR(i + 1, writeListJSON.getInt(i));
				writeList.add(write);
			}
			q.setWriteList(writeList);
		}
		{//ANSWER LIST
			JSONArray answerListJSON = new JSONArray(resultSet.getString(8));
			int length = answerListJSON.length();
			ArrayList<QuestionAN> answerList = new ArrayList<QuestionAN>(length);
			for (int i = 0; i < length; i++) {
				JSONObject answerJSONOBject = answerListJSON.getJSONObject(i);
				QuestionAN answer = new QuestionAN(i + 1, answerJSONOBject.getString(AN_TYPE));
				answer.setScoreInt(answerJSONOBject.getInt(AN_SCORE));
				if (q.getType().equals(Question.TYPE_SELECTION)) {
					JSONArray anSelect = answerJSONOBject.getJSONArray(AN_SELECT);
					for (int j = 0; j < anSelect.length(); j++) {

						answer.addSelection(q.getSelection(anSelect.getInt(j)));
					}
				} else if (answerJSONOBject.has(AN_WRITE)) {
					JSONArray anWrite = answerJSONOBject.getJSONArray(AN_WRITE);
					for (int j = 0; j < anWrite.length(); j++) {

						answer.addWrite(anWrite.getString(j));
					}
				}
				answerList.add(answer);
			}
			q.setAnswerList(answerList);
		}
		{//ANC
			JSONArray ancListJSON = new JSONArray(resultSet.getString(9));
			int length = ancListJSON.length();
			ArrayList<QuestionAN> questionANC = new ArrayList<QuestionAN>(length);
			for (int i = 0; i < length; i++) {
				questionANC.add(q.getAnswer(ancListJSON.getInt(i)));
			}
			q.setQuestionANC(questionANC);
		}
		
		q.setExaminerInsertType(resultSet.getString(10));
		q.setTimeStyle(resultSet.getString(11));
		if (q.getTimeStyle().equals(Question.QUESTION_TIME_OUT)) {

			q.setTimeOutDuration(resultSet.getLong(13));
		} else {
			q.setLimitPoints(new Pair(resultSet.getLong(12), resultSet.getLong(13)));
		}
		
		ArrayList<QuestionAN> answerList = q.getAnswerList();
		int maxScore = 0;
		for (QuestionAN questionAN : answerList) {
			maxScore += questionAN.getScoreInt();
		}
		q.setMaxScore(maxScore);
		System.out.println("Question " + maxScore);
	}

	@Override
	public int save() throws SQLException {
		throw new UnsupportedOperationException("Không dùng phương thức này");
	}

	@Override
	public int insert() throws SQLException {

		//Selection List
		JSONArray selectionList = new JSONArray();

		for (QuestionS selection : question.getSelectionList()) {
			selectionList.put(selection.getContent());
		}
		//Answer + Score List
		JSONArray answerScoreList = new JSONArray();

		for (QuestionAN answer : question.getAnswerList()) {
			JSONObject an = new JSONObject();
			an.put(AN_TYPE, answer.getType());
			an.put(AN_SCORE, answer.getScoreInt());

			List<QuestionS> selectionList2 = answer.getSelectionList();
			int length = selectionList2.size();
			for (int i = 0; i < length; i++) {
				an.append(AN_SELECT, selectionList2.get(i).getSelectionNumber());
			}

			List<String> writeList = answer.getWriteList();
			int length2 = writeList.size();
			for (int i = 0; i < length2; i++) {
				an.append(AN_WRITE, writeList.get(i));
			}
			answerScoreList.put(an);
		}

		JSONArray writeList = new JSONArray();

		for (QuestionWR write : question.getWriteList()) {
			writeList.put(write.getMaxChar());
		}

		JSONArray ancList = new JSONArray();

		for (QuestionAN answer : question.getQuestionANC()) {
			ancList.put(answer.getAnswerNumber());
		}

		String insertQuestionUpdateString = "INSERT INTO "
				+ TABLE_QUESTION
				+ "(questionNo, test_id, type, question_content, selection_list, write_list, answer_score_list, anc_list, ins_type, timeout_style, timeout_duration_1, timeout_duration_2) VALUE("
				+ +question.getQuestionNo() + "," + question.getTestId() + ",'" + question.getType() + "','"
				+ question.getContent() + "','" + selectionList.toString() + "','" + writeList.toString() + "','"
				+ answerScoreList.toString() + "','" + ancList.toString() + "','" + question.getExaminerInsertType()
				+ "','" + question.getTimeStyle() + "'," + question.getTimeOutDuration1() + ","
				+ question.getTimeOutDuration() + ")";
		try {
			initConnection();
			int rs = executeUpdate(insertQuestionUpdateString);
			if (rs > 0) {
				return 0;
			} else {
				return 1;
			}
		} finally {
			freeResources();
		}
	}

	public int insertAnswer(int examineeId) throws SQLException {

		JSONArray selectionJSON = new JSONArray();
		ArrayList<Integer> examineeSelection = this.question.getExamineeSelection();
		for (Integer selection : examineeSelection) {
			selectionJSON.put(selection);
		}

		JSONArray writeJSON = new JSONArray();
		ArrayList<String> examineeWrite = this.question.getExamineeWrite();

		for (String write : examineeWrite) {
			writeJSON.put(write);
		}

		String insertAnswerUpdateString = "INSERT INTO " + TABLE_ANSWER
				+ "(`question_id`, `examinee_id`, `selections`, `writes`, `score`, `ins_content`, `used_time`) VALUE("
				+ this.question.getId() + "," + examineeId + ",'" + selectionJSON.toString() + "','"
				+ writeJSON.toString() + "'," + this.question.getScore() + ",'" + this.question.getInsertContent()
				+ "',"+ this.question.getUsedTime() +")";

		try {
			initConnection();
			int rs = executeUpdate(insertAnswerUpdateString);
			if (rs > 0) return 1;
			else return 0;
		} finally {
			freeResources();
		}
	}

	@Override
	public int delete() throws SQLException {
		throw new UnsupportedOperationException("Không dùng phương thức này");
	}

	@Override
	public void clear() {
		this.question = null;
	}

	public Collection<? extends Question> listAllQuestions(Test test) throws SQLException {
		String queryString = "SELECT " + FIELD_NAME + " FROM " + TABLE_QUESTION + " WHERE `test_id` = " + test.getId();
		try {
			initConnection();
			executeQuery(queryString);
			ArrayList<Question> questions = new ArrayList<Question>();
			while (resultSet.next()) {
				Question q = new Question();
				loadQuestion(q, resultSet);
				questions.add(q);
			}
			return questions;
		} finally {
			freeResources();
		}
	}

	/* - Getter and Setter - */
	public  String getAnswerScoreList() {
		String result="";
		ArrayList<QuestionAN> t=question.getAnswerList();
		for (QuestionAN ans : t) {
			result+=ans.getWriteList()+" : "+ans.getScoreInt()+"<br>";
		}
		return result;
	}
	public ArrayList<QuestionSC> getScoreList() {
		return question.getScoreList();
	}
	public String getExaminerInsertType(){
		return question.getExaminerInsertType();
	}
	public String getInsertContent(){
		return question.getInsertContent();
	}
	public ArrayList<String> getExamineeWrite(){
		return question.getExamineeWrite();
	}
	public ArrayList<Integer> getExamineeSelection(){
		return question.getExamineeSelection();
	}
	public int getScore(){
		return question.getScore();
	}
	public String getType()
	{
		return question.getType();
	}
	public String getContent(){
		return question.getContent();
	}
	public ArrayList<QuestionWR> getWriteList()
	{
		return question.getWriteList();
	}
	public ArrayList<QuestionS> getSelectionList(){
		return question.getSelectionList();
	}
	public int getQuestionNo() {
		return question.getQuestionNo();
	}

	public void setQuestionNo(int questionNo) {
		question.setQuestionNo(questionNo);
	}

	public void setTestId(int testId) {
		question.setTestId(testId);
	}

	public Question getQuestion() {
		return question;
	}

	public void setQuestion(Question question) {
		this.question = question;
	}

	public int getId() {
		return question.getId();
	}

	public void setId(int id) {
		question.setId(id);
	}

	public int getTestId() {
		return question.getTestId();
	}
	public long getUsedTime(){
		return question.getUsedTime();
	}
//lấy list câu hỏi và câu trả lời cua thi sinh
	public List <QuestionBean> listAllQuestionByTestId(int testId,int examineeId) throws SQLException {
		String queryString = "SELECT " + FIELD_NAME + " FROM " + TABLE_QUESTION + " WHERE `test_id` = " + testId;

		try {
			initConnection();
			executeQuery(queryString);
			List<QuestionBean> questions = new LinkedList<QuestionBean>();
			while (resultSet.next()) {
				
				QuestionBean q = new QuestionBean();
				loadQuestion(q.question, resultSet);
				q.loadAnswer(examineeId);
				questions.add(q);

			}
			return questions;
		} finally {
			freeResources();
		}
	}

}
